package com.example.wisdombookstore.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.wisdombookstore.entity.*;

import com.example.wisdombookstore.mapper.TbCheckResultMapper;
import com.example.wisdombookstore.mapper.TbCheckTaskMapper;
import com.example.wisdombookstore.mapper.TbClerkMapper;

import com.example.wisdombookstore.mapper.*;

import com.example.wisdombookstore.service.ICheckTaskService;
import com.example.wisdombookstore.util.DateTime;
import com.example.wisdombookstore.util.IdWorker;
import com.example.wisdombookstore.util.ResponseResult;
import com.example.wisdombookstore.util.StateConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.*;
import java.util.List;

/**
 * @Author: MaHan
 * @Date: Created in 14:50 2020/10/25
 * @Description:
 * @program: IntelliJ IDEA
 * @ClassName: CheckTaskServiceImpl
 */
@Service
@Slf4j
public class CheckTaskServiceImpl extends ServiceImpl<TbCheckTaskMapper,TbCheckTask> implements ICheckTaskService {
    @Resource
    private IdWorker idWorker;

    @Resource
    private TbCheckTaskMapper tbCheckTaskMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private TbClerkMapper tbClerkMapper;

    @Resource
    private TbBookTypeMapper tbBookTypeMapper;

    @Resource
    private TbBookMapper tbBookMapper;

    @Resource
    private TbBookInfoMapper tbBookInfoMapper;

    @Resource
    private RlCheckBookTypeMapper rlCheckBookTypeMapper;

    @Resource
    private RlBookTypeInfomMapper rlBookTypeInfomMapper;

    @Resource
    private TbCheckDeficiencyMapper tbCheckDeficiencyMapper;

    @Resource
    private TbCheckResultMapper tbCheckResultMapper;

    @Override
    public ResponseResult addCheck(TbCheckTask tbCheckTask) {
        log.info("进入盘点任务添加方法"+tbCheckTask.toString());
        Long tbClerkCode = tbCheckTask.getTbClerkCode();
        log.info("查询盘点人是否是合法员工");
        LambdaQueryWrapper<TbClerk> last = new QueryWrapper<TbClerk>()
                .lambda()
                .eq(TbClerk::getCode, tbCheckTask.getTbClerkCode())
                .eq(TbClerk::getStatus, StateConstant.TBCLERK_STATUS_WORK)
                .last("limit 1");
        TbClerk tbClerk = this.tbClerkMapper.selectOne(last);
        System.err.println(tbClerk);
        if (tbClerk == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "非法盘点员");
        }
        TbCheckTask tbCheckTask1 = new TbCheckTask();
        tbCheckTask1.setId(null);
        tbCheckTask1.setCode(idWorker.nextId());
        tbCheckTask1.setIsDel(StateConstant.OBJECT_DEL_NORMAL);
        tbCheckTask1.setCreateTime(new Date());
        tbCheckTask1.setUpdateTime(null);
        tbCheckTask1.setStatus(StateConstant.TBCHECKTASK_STATUS_STAY);
        tbCheckTask1.setStartCheckDate(tbCheckTask.getStartCheckDate());
        tbCheckTask1.setTypeJoint(tbCheckTask.getTypeJoint());
        tbCheckTask1.setTbClerkCode(tbCheckTask.getTbClerkCode());
        //        //获取系统时间
        //        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //        Calendar c = Calendar.getInstance();
        //        System.out.println("当前日期:"+sf.format(c.getTime()));
        //        //时间增加一天
        //        c.add(Calendar.DAY_OF_MONTH, 1);

        tbCheckTask1.setEndCheckDate(tbCheckTask.getEndCheckDate());
        //分割盘点类型唯一标识  查询类型所属书籍数量
        log.info("对象查询"+tbCheckTask1);
        log.info("分割盘点类型唯一标识  查询类型所属书籍数量");
        String[] split = tbCheckTask.getTypeJoint().split(",");
        int num = 0;
        for (String a : split) {
            log.info("书籍类型code"+a);
            RlBookTypeInfo bookTypeInfo1 = rlBookTypeInfomMapper.selectOne(
                    new QueryWrapper<RlBookTypeInfo>()
                            .lambda()
                            .eq(RlBookTypeInfo::getTbBookTypesCode, a)
                            .last("limit 1"));
            log.info("书籍详细信息"+bookTypeInfo1);
            TbBookInfo bookInfo1 = tbBookInfoMapper.selectOne(
                    new QueryWrapper<TbBookInfo>()
                            .lambda()
                            .eq(TbBookInfo::getCode, bookTypeInfo1.getTbBookInfoCode())
                            .last("limit 1"));
            num += bookInfo1.getNumber();
        }
        tbCheckTask1.setTargetNumber(num);
        //添加任务
        log.info("添加任务" + tbCheckTask1);
        int insert = this.tbCheckTaskMapper.insert(tbCheckTask1);
        if (insert == 0) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "创建盘点任务失败");
        }
        //分割盘点类型唯一标识  查询类型  添加到盘点类型中间表
        log.info("分割盘点类型唯一标识  查询类型  添加到盘点类型中间表");
        int insert1 = 0;
        for (String a : split) {
            TbBookType tbBookType = tbBookTypeMapper.selectOne(
                    new QueryWrapper<TbBookType>()
                            .lambda()
                            .eq(TbBookType::getCode, a)
                            .last("limit 1"));
            RlCheckBookType rlCheckBookType = new RlCheckBookType();
            rlCheckBookType.setId(null);
            rlCheckBookType.setCode(idWorker.nextId());
            rlCheckBookType.setIsDel(StateConstant.OBJECT_DEL_NORMAL);
            rlCheckBookType.setCreateTime(new Date());
            rlCheckBookType.setUpdateTime(null);
            rlCheckBookType.setTbCheckTaskCode(tbCheckTask1.getCode());
            rlCheckBookType.setTbBookTypeCode(tbBookType.getCode());
            insert1 += rlCheckBookTypeMapper.insert(rlCheckBookType);
        }
        if (insert1 == 0) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "创建盘点任务失败");
        }
        return new ResponseResult(true, StateConstant.RESPONSERESULT_CODE_FALSE, "创建盘点任务成功");
    }




    @Override
    public ResponseResult updateCheckRedis(TbCheckTask tbCheckTask, Long rfid, Long type) {
        //查询盘点员是否合法
        LambdaQueryWrapper<TbClerk> last = new QueryWrapper<TbClerk>()
                .lambda()
                .eq(TbClerk::getCode, tbCheckTask.getTbClerkCode())
                .eq(TbClerk::getStatus, StateConstant.TBCLERK_STATUS_WORK)
                .last("limit 1");
        TbClerk tbClerk = this.tbClerkMapper.selectOne(last);
        if (tbClerk == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "非法盘点员");
        }
        //查询盘点任务是否存在或者已经盘点结束
        LambdaQueryWrapper<TbCheckTask> last1 = new QueryWrapper<TbCheckTask>()
                .lambda()
                .eq(TbCheckTask::getStatus, StateConstant.TBCHECKTASK_STATUS_START)
                .eq(TbCheckTask::getCode, tbCheckTask.getCode())
                .last("limit 1");
        TbCheckTask checktask = this.getOne(last1);
        if (checktask == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "无盘点任务");
        }

        //判断盘点任务是否开始或者已经超时
        //系统时间
        long time = DateTime.getDateTime().getTime();
        //盘点任务开始时间
        long startCheckDate = DateTime.getDateTime(checktask.getStartCheckDate()).getTime();
        //盘点任务结束时间
        long endCheckDate = DateTime.getDateTime(checktask.getEndCheckDate()).getTime();
        if (time < startCheckDate) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "盘点任务还没开始");
        }
        if (time > endCheckDate) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "盘点任务已经结束");
        }
        //根据盘点任务类型+盘点类型 ， 图书rfid判断是放在本次盘点任务中
        Boolean member = redisTemplate.opsForSet().isMember(tbCheckTask.getCode(), rfid);
        if (member) {
            redisTemplate.opsForSet().remove(tbCheckTask.getCode(), rfid);
            return new ResponseResult(true, StateConstant.RESPONSERESULT_CODE_TRUE, "此图书盘点成功");
        }
        return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "此图书不在本次任务中");

    }

    @Override
    public ResponseResult showTbook(TbCheckTask tbCheckTask) {
        System.err.println(tbCheckTask);
        if(tbCheckTask==null){
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "参数错误");
        }
        //查询盘点员是否合法
        LambdaQueryWrapper<TbClerk> last = new QueryWrapper<TbClerk>()
                .lambda()
                .eq(TbClerk::getCode, tbCheckTask.getTbClerkCode())
                .eq(TbClerk::getStatus, StateConstant.TBCLERK_STATUS_WORK)
                .last("limit 1");
        TbClerk tbClerk = this.tbClerkMapper.selectOne(last);
        if (tbClerk == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "非法盘点员");
        }
        Set members = redisTemplate.opsForSet().members(tbCheckTask.getCode());
        ArrayList<TbBook> objects = new ArrayList<>();
        TbBook tbBook = null;
        for (Object set1 : members) {
            System.err.println(set1);
            LambdaQueryWrapper<TbBook> eq = new QueryWrapper<TbBook>()
                    .lambda()
                    .eq(TbBook::getRfIdCode, set1)
                    .last("limit 1");
            tbBook = tbBookMapper.selectOne(eq);
            objects.add(tbBook);
            System.err.println(tbBook);
            LambdaQueryWrapper<TbBookInfo> eq1 = new QueryWrapper<TbBookInfo>()
                    .lambda()
                    .eq(TbBookInfo::getCode, tbBook.getTbBookInfoCode());
            TbBookInfo tbBookInfo = this.tbBookInfoMapper.selectOne(eq1);
            //带走
            tbBook.setTbBookInfo(tbBookInfo);
        }

        return new ResponseResult(true, StateConstant.RESPONSERESULT_CODE_TRUE, "查询成功", objects);
    }

    @Override
    public ResponseResult checkResult(TbCheckResult tbCheckResult, Long tbClerkCode) {
        System.err.println("   +++++    ");
        //查询盘点员是否合法
        LambdaQueryWrapper<TbClerk> last = new QueryWrapper<TbClerk>()
                .lambda()
                .eq(TbClerk::getCode, tbClerkCode)
                .eq(TbClerk::getStatus, StateConstant.TBCLERK_STATUS_WORK)
                .last("limit 1");
        TbClerk tbClerk = this.tbClerkMapper.selectOne(last);
        if (tbClerk == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "非法盘点员");
        }
        //查询盘点任务是否存在或者已经盘点结束
        LambdaQueryWrapper<TbCheckTask> last1 = new QueryWrapper<TbCheckTask>()
                .lambda()
                .eq(TbCheckTask::getStatus, StateConstant.TBCHECKTASK_STATUS_START)
                .eq(TbCheckTask::getCode, tbCheckResult.getTbCheckTaskCode())
                .last("limit 1");
        TbCheckTask checktask = this.getOne(last1);
        if (checktask == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "盘点任务未开始");
        }
        TbCheckResult tbCheckResult1 = new TbCheckResult();
        tbCheckResult1.setId(null);
        tbCheckResult1.setCode(idWorker.nextId());
        tbCheckResult1.setIsDel(StateConstant.OBJECT_DEL_NORMAL);
        tbCheckResult1.setCreateTime(new Date());
        tbCheckResult1.setUpdateTime(null);
        tbCheckResult1.setTbCheckTaskCode(tbCheckResult.getTbCheckTaskCode());
        //添加目标数量
        tbCheckResult1.setTargetNumber(checktask.getTargetNumber());

        //分割盘点类型
        String[] split = checktask.getTypeJoint().split(",");
        int size = 0;
        TbCheckDeficiency tbCheckDeficiency = null;
        for (String a : split) {
            Set members = null;
            //查询redis中还有图书未盘点
            members = redisTemplate.opsForSet().members(tbCheckResult.getTbCheckTaskCode());
            for (Object set1 : members) {
                LambdaQueryWrapper<TbBook> eq = new QueryWrapper<TbBook>()
                        .lambda()
                        .eq(TbBook::getRfIdCode, set1.toString())
                        .last("limit 1");
                TbBook tbBook = tbBookMapper.selectOne(eq);
                tbCheckDeficiency = new TbCheckDeficiency();
                tbCheckDeficiency.setRfIdCode(tbBook.getRfIdCode());
                tbCheckDeficiency.setTitle(tbBook.getTitle());
                tbCheckDeficiency.setPrice(tbBook.getPrice());
                tbCheckDeficiency.setId(null);
                tbCheckDeficiency.setCode(idWorker.nextId());
                tbCheckDeficiency.setCreateTime(new Date());
                tbCheckDeficiency.setUpdateTime(null);
                tbCheckDeficiency.setIsDel(StateConstant.OBJECT_DEL_NORMAL);
                tbCheckDeficiency.setTbCheckTaskCode(tbCheckResult.getTbCheckTaskCode());
                this.tbCheckDeficiencyMapper.insert(tbCheckDeficiency);
                //删除redis中未盘点的数据
                System.err.println(tbCheckResult.getTbCheckTaskCode() + "+++++++++++" + set1);
                redisTemplate.opsForSet().remove(tbCheckResult.getTbCheckTaskCode(), set1);
                //Object pop = redisTemplate.opsForSet().pop(tbCheckResult.getTbCheckTaskCode());

            }
            //未盘点数量
            size += members.size();
        }
        //添加实际数量
        tbCheckResult1.setRealNumber(checktask.getTargetNumber() - size);
        //添加缺少数量
        tbCheckResult1.setLackNumber(size);
        int insert = this.tbCheckResultMapper.insert(tbCheckResult1);
        if (insert == 1) {
            //添加任务结果唯一标识
            checktask.setTbCheckResultCode(tbCheckDeficiency.getCode());
            checktask.setStatus(StateConstant.TBCHECKTASK_STATUS_COMPLETE);
            int i = this.tbCheckTaskMapper.updateById(checktask);
            if (i == 1) {
                return new ResponseResult(true, StateConstant.RESPONSERESULT_CODE_TRUE, "提交成功");
            }
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "提交失败1");
        }
        return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "提交失败2");
    }


    @Override
    public ResponseResult findAllCheck(TbCheckTask tbCheckTask) {
        //查询盘点员是否合法
        LambdaQueryWrapper<TbClerk> last = new QueryWrapper<TbClerk>()
                .lambda()
                .eq(TbClerk::getCode, tbCheckTask.getTbClerkCode())
                .eq(TbClerk::getStatus, StateConstant.TBCLERK_STATUS_WORK)
                .last("limit 1");
        TbClerk tbClerk = this.tbClerkMapper.selectOne(last);
        if (tbClerk == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "非法盘点员");
        }
        //查询盘点任务是否存在或者已经盘点结束
        LambdaQueryWrapper<TbCheckTask> last1 = new QueryWrapper<TbCheckTask>()
                .lambda()
                .eq(TbCheckTask::getStatus, StateConstant.TBCHECKTASK_STATUS_STAY)
                .eq(TbCheckTask::getCode, tbCheckTask.getCode())
                .last("limit 1");
        TbCheckTask checktask = this.getOne(last1);
        if (checktask == null) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "无盘点任务");
        }
        //判断盘点任务是否开始或者已经超时
        //系统时间
        long time = DateTime.getDateTime().getTime();
        //盘点任务开始时间
        long startCheckDate = DateTime.getDateTime(checktask.getStartCheckDate()).getTime();
        //盘点任务结束时间
        long endCheckDate = DateTime.getDateTime(checktask.getEndCheckDate()).getTime();
        if (time < startCheckDate) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "盘点任务还没开始");
        }
        if (time > endCheckDate) {
            return new ResponseResult(false, StateConstant.RESPONSERESULT_CODE_FALSE, "盘点任务已经结束");
        }

        checktask.setStatus(StateConstant.TBCHECKTASK_STATUS_START);
        boolean b1 = this.updateById(checktask);
        System.err.println("修改任务状态"+b1);
        //分解盘点类型
        String[] split = checktask.getTypeJoint().split(",");
        //存放盘点任务类型
        ArrayList<TbBookType> tbBookInfos = new ArrayList<>();
        for (String a : split) {
            //查询盘点任务类型
            System.err.println("任务类型code"+a);
            LambdaQueryWrapper<TbBookType> eq2 = new QueryWrapper<TbBookType>()
                    .lambda()
                    .eq(TbBookType::getCode, a)
                    .last("limit 1");
            TbBookType tbBookType = this.tbBookTypeMapper.selectOne(eq2);
            System.err.println(tbBookType);
            //存在
            tbBookInfos.add(tbBookType);
            //根据类型查询对应书籍信息
            LambdaQueryWrapper<RlBookTypeInfo> eq = new QueryWrapper<RlBookTypeInfo>()
                    .lambda()
                    .eq(RlBookTypeInfo::getTbBookTypesCode, a);
            RlBookTypeInfo bookTypeInfo = this.rlBookTypeInfomMapper.selectOne(eq);
            System.err.println(bookTypeInfo);
            //根据书籍信息查询所对应的所有图书
            LambdaQueryWrapper<TbBook> eq1 = new QueryWrapper<TbBook>()
                    .lambda()
                    .eq(TbBook::getTbBookInfoCode, bookTypeInfo.getTbBookInfoCode());
            List<TbBook> tbBooks = this.tbBookMapper.selectList(eq1);
            System.err.println(tbBooks.toString());
            //把 查询出来的图书rfid存放在redis中
            for (TbBook b : tbBooks) {
                //key  盘点任务+盘点的类型    value 图书的rfid
                System.err.println("redis");
                this.redisTemplate.opsForSet().add(tbCheckTask.getCode(), b.getRfIdCode());
            }

        }
        return new ResponseResult(true, StateConstant.RESPONSERESULT_CODE_TRUE, "查询成功", tbBookInfos);
    }

    /**
     * TODO &马晗& 根据负责人查询盘点任务
     *
     * @param tbCherkCode: 负责人标识
     * @return: com.example.wisdombookstore.util.ResponseResult
     * @Author &马晗&
     * @Description
     * @Date 15:42 2020/10/25
     **/
    @Override
    public ResponseResult inventoryUserFindCode(Long tbCherkCode) {
        if(tbCherkCode==null){
            return new ResponseResult(true,StateConstant.RESPONSERESULT_CODE_TRUE,"查询失败");
        }
        //提示信息
        ResponseResult result = new ResponseResult();
        //根据负责人查询任务
        QueryWrapper<TbCheckTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbCheckTask::getTbClerkCode, tbCherkCode);
        List<TbCheckTask> tbCheckTasks = this.tbCheckTaskMapper.selectList(queryWrapper);
        if(tbCheckTasks==null){
            return new ResponseResult(true,StateConstant.RESPONSERESULT_CODE_TRUE,"查询成功,暂无任务");
        }
        //放入返回信息
        result.setResult(tbCheckTasks);
        return result;
    }
    /**
     * TODO &马晗& 查询所有盘点任务
     * @param currentPage:
     * @param pageSize:
     * @return: com.example.wisdombookstore.util.ResponseResult
     * @Author &马晗&
     * @Description
     * @Date 21:33 2020/10/29
     **/
    @Override
    public ResponseResult inventoryUserFind(Integer currentPage, Integer pageSize) {
        //提示信息
        ResponseResult result = new ResponseResult();
        //分页插件
        Page<TbCheckTask> page = new Page<>(currentPage, pageSize);
        //mybatis puls 插件
        LambdaQueryWrapper<TbCheckTask> tbCheckTaskLambdaQueryWrapper = new QueryWrapper<TbCheckTask>()
                .lambda()
                .orderByDesc(TbCheckTask::getStartCheckDate);
        //查询所有盘点任务
        Page<TbCheckTask> tbCheckTaskPage = this.tbCheckTaskMapper.selectPage(page, tbCheckTaskLambdaQueryWrapper);
        //取出集合
        List<TbCheckTask> tbCheckTasks = tbCheckTaskPage.getRecords();
        for (TbCheckTask tbCheckTask : tbCheckTasks) {
            //获取负责人标识
            Long tbUserCode = tbCheckTask.getTbClerkCode();
            QueryWrapper<TbClerk> qwu = new QueryWrapper<>();
            qwu.lambda().eq(TbClerk::getCode, tbUserCode);
            TbClerk tbClerk = tbClerkMapper.selectOne(qwu);
            //带走
            tbCheckTask.setTbClerk(tbClerk);
        }
        //判断集合是否为空
        if (tbCheckTasks.size() == StateConstant.HAVEHOT) {
            //如果为空提示没有该任务
            result.setFailMessage("没有任务");
        }
        //如果不为空 返回数据
        result.setResult(tbCheckTaskPage);
        return result;
    }
}








